package net.vsame.url2sql.url.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.vsame.url2sql.config.ConfigFactory;
import net.vsame.url2sql.helper.Url2SqlContext;
import net.vsame.url2sql.helper.WebHelper;
import net.vsame.url2sql.url.Interceptor;


public class UrlMapping {
	
	private static UrlMapping mapping = new UrlMapping();

	private static String RUNTIM_EXCEPTION = "java.lang.RuntimeException: ";
	
	private Map<String, UrlConfig> urlSqlMap = new HashMap<String, UrlConfig>();
	private List<Interceptor> interceptors = new ArrayList<Interceptor>();
	
	public static UrlMapping getMapping(){
		return mapping;
	}
	
	/**
	 * 根据Url取得Sql
	 * @param url
	 * @return
	 */
	public UrlConfig getConfig(String url){
		if(!url.startsWith("/")){
			url = "/" + url;
		}
		return urlSqlMap.get(url);
	}
	
	public void addUrlConfig(UrlConfig urlConfig){
		urlSqlMap.put(urlConfig.getUrl(), urlConfig);
	}
	
	public void addUrlConfig(Map<String, UrlConfig> map){
		urlSqlMap.putAll(map);
	}
	
	public void addInterceptor(Interceptor i){
		interceptors.add(i);
	}
	
	public void addInterceptor(List<Interceptor> is){
		interceptors.addAll(is);
	}

	public void reload() {
		urlSqlMap.clear();
		interceptors.clear();
		//从配置文件中加载
		ConfigFactory.load(UrlMapping.mapping);
		interceptors.add(new ActionInterceptor());
		//加载拦截器中 初始化方法　
		for(Interceptor i : interceptors) {
			i.init(this);
		}
	}
	
	public void invoke(){
		try{
			new Chain().next();
		}catch (Exception e) {
			Url2SqlContext c = WebHelper.getContext();
			String msg = null;
			if(e.getCause() != null){
				msg = e.getCause().getMessage();
			}else {
				msg = e.getMessage();
			}
			c.error(e, handleMsg(msg));
			try {
				c.getConn().rollback();//回滚
			} catch (Exception e1) {
			}
		}
	}
	
	/**
	 * 处理消息, 尽可能把 java.lang.RuntimeException这样的移除
	 * @param msg
	 */
	private static String handleMsg(String msg) {
		if(msg == null){
			return msg;
		}
		if(msg.startsWith(RUNTIM_EXCEPTION)){
			msg = msg.substring(RUNTIM_EXCEPTION.length(), msg.length()-1);
		}
		return msg;
	}
	
	public static void main(String[] args) {
		RUNTIM_EXCEPTION = "java.lang.RuntimeException: ";
		String msg = "java.lang.RuntimeException: ${consultantId} must exist.";
		System.out.println(handleMsg(msg));
	}

	public class Chain {
		private int i = -1;
		public void next(){
			i++;
			if(i<interceptors.size()){
				interceptors.get(i).invoke(this);
			}
		}
	}

}
